# -*- coding:utf-8 -*-
import Tkinter as tk
import tkFileDialog
import tkMessageBox
from transcode_arc import *
import io
import json
import threading
import time
from transform import *
import arcpy
import requests

#区划后缀列表
qhendstrs = [u'村村委会',u'村委会',u'村民委员会',u'社区',u'居委会']
#户籍前缀列表
hjfrontstrs = [u'办事处',u'镇',u'乡']
#户籍后缀列表
hjendstrs = [u'村',u'社区',u'居委会']

#提取户籍村居简称
def gethjsimple(address):
    #提取简称
    for front in hjfrontstrs:
        frontpos = address.find(front)
        if frontpos>0:
            okfront = front
            break
    for end in hjendstrs:
        endpos  = address.find(end)
        if endpos>0:
            break
    print address,frontpos,endpos,okfront,len(okfront),address[frontpos+len(okfront):endpos]
    if  frontpos> 0 and endpos>0:
        return address[frontpos+len(okfront):endpos]
    return ''

#生成区划简称查询字典
def getareadict(areacodes):
    areacodedict = {}
    for area in areacodes:
        #提取简称
        for end in qhendstrs:
            endpos = area[0].find(end)
            if  endpos>0:
                simplename = area[0][0:endpos]
                areacodedict[simplename] = area
                break
    return areacodedict

def execProcess():
    datasource = path_shp.get()   #ur'村边界_bd.shp'
    print datasource
    #先转百度坐标
    outFeature = datasource[0:datasource.find('.shp')]+'_bd.shp'
    if arcpy.Exists(outFeature):
        arcpy.Delete_management(outFeature)
    print datasource,outFeature
    arcpy.CopyFeatures_management(datasource, outFeature)
    transformFeature(outFeature)
    ###待加入异常处理
    coder = Transcoder(outFeature, ['name', 'area_code'])
    #读取边界文件区划库
    areacodes = coder.codes()
    #生成区划简称字典
    areacodedict = getareadict(areacodes)
    ###待加入异常处理
    with open(u'区划代码.csv','w') as fqh:
        for d in areacodedict:
            fqh.write('%s,%s,%s\n'%(d,areacodedict[d][0],areacodedict[d][1]))
    #输出csv表头
    ###待加入异常处理
    with open(u'匹配结果'+time.strftime("%Y_%m_%d_%H_%M_%S", time.localtime()) +'.csv','w') as fout:
        fout.write('地址,匹配村居名,匹配村居码,经度,纬度,理解程度,是否精确查找,打点精度,地址类型,村居简称,简称匹配村居名,简称匹配村居码\n')
        #已查询缓存
        reslist = {}
        with io.open(path_txt.get(), "r",encoding='utf-8') as f:
            for index,line in enumerate(f.readlines()):                
                inAddress = line.strip()  #去掉头尾空字符
                if  inAddress=='':
                    print u'空行'
                    continue
                #先在缓存中查找
                if inAddress in reslist:
                    result = reslist[inAddress]
                    print u'读缓存'
                else:
                    #空间查询匹配
                    result = coder.trans(inAddress)
                    result['addr'] = inAddress
                    reslist[inAddress] = result
                    #区划简称匹配
                    #提取户籍简称
                    hjsimple = gethjsimple(inAddress)
                    result['hjsimple'] = hjsimple
                    if hjsimple in areacodedict and hjsimple != '':
                        result['qhname'] = areacodedict[hjsimple][0]
                        result['qhcode'] = areacodedict[hjsimple][1]
                    else:
                        result['qhname'] = ''
                        result['qhcode'] = ''
                fout.write(u'%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n' % (inAddress,result['coding']['name'],result['coding']['area_code'],result['location']['lng']
                ,result['location']['lat'],result['comprehension'],result['precise'],result['confidence'],result['level'],result['hjsimple'],result['qhname'],result['qhcode']))
                outinfo.insert('end','%s:%s\n' %(index,inAddress))

def selectPath(type,textui):
    #选择文件path_接收文件地址
    path_ = tkFileDialog.askopenfilename(filetypes=[(type,'*.'+type)])
    #通过replace函数替换绝对文件地址中的/来使文件可被程序读取 
    #注意：\\转义后为\，所以\\\\转义后为\\
    path_=path_.replace("/","\\\\")
    #path设置path_的值
    textui.set(path_)

def createMainForm():
    #生成UI
    main_box= tk.Tk()
    main_box.title('第七次人口普查地址匹配工具')
    main_box.withdraw()
    #变量path
    global path_shp
    path_shp = tk.StringVar()
    global path_txt
    path_txt = tk.StringVar()
    #说明
    info = tk.Text(main_box)
    info.insert('insert',
'''输入的地址列表为文本文件，每行一个地址，utf8编码
边界文件为shp格式，注意四经普边界和人普边界的数据格式不一样，正确配置村居名称和代码字段
输出结果为同目录的'地址匹配.csv'文件
输出结果字段说明：
理解程度：
    描述地址理解程度。分值范围0-100，分值越大，对地址理解程度越高
打点精度：
    即坐标点的误差范围，分值范围0-100，分值越大，精度越高
    confidence=100，解析误差绝对精度小于20m
    confidence=50，解析误差绝对精度小于1000m
是否精确查找：
    位置的附加信息，是否精确查找。1为精确查找，即准确打点；0为不精确，即模糊打点
地址类型：
    能精确理解的地址类型，包含：UNKNOWN、国家、省、城市、区县、乡镇、村庄、道路、地产小区、商务大厦、政府机构、交叉路口、商圈、生活服务、休闲娱乐、餐饮、宾馆、购物、金融、教育、医疗 、工业园区 、旅游景点 、汽车服务、火车站、长途汽车站、桥 、停车场/停车区、港口/码头、收费区/收费站、飞机场 、机场 、收费处/收费站 、加油站、绿地、门址
    ''')
    info.pack(side='top',fill='both',expand='yes')

    #输入框绑定变量path
    frm1 = tk.Frame(main_box)
    frm1.pack(side='top',fill='both',expand='yes')
    tk.Label(frm1,text = "边界文件").pack(side='left')
    tk.Entry(frm1, textvariable = path_shp,width=50).pack(side='left')
    tk.Button(frm1, text = "选择文件", command = lambda:selectPath('shp',path_shp)).pack(side='left')

    frm2 = tk.Frame(main_box)
    frm2.pack(side='top',fill='both',expand='yes')
    tk.Label(frm2,text = "地址文件").pack(side='left')
    tk.Entry(frm2, textvariable = path_txt,width=50).pack(side='left')
    tk.Button(frm2, text = "选择文件", command = lambda:selectPath('txt',path_txt)).pack(side='left')

    #线程调用command=execThread,直接调用command=execProcess
    tk.Button(main_box, text = "执行匹配", command = execThread).pack(side='top',fill='both',expand='yes')
    #输出处理进度
    global outinfo
    outinfo = tk.Text(main_box,height=10)
    outinfo.pack(side='top')
    loginform(main_box)
    main_box.mainloop()

def execThread():
    T = threading.Thread(target=execProcess)
    T.start()

def loginform(main_box):
    logindlg = tk.Toplevel()
    logindlg.title('第七次人口普查地址匹配工具')
    logindlg.wm_attributes('-topmost',1)
    def quitapp():
        main_box.quit()
    logindlg.protocol('WM_DELETE_WINDOW', quitapp)

    print logindlg
    #输入框绑定变量path
    frm1 = tk.Frame(logindlg)
    frm1.pack(side='top',fill='both',expand='yes')
    tk.Label(frm1,text = "手机号").pack(side='left')
    global mobile
    mobile = tk.Entry(frm1, width=50)
    mobile.pack(side='left')

    frm2 = tk.Frame(logindlg)
    frm2.pack(side='top',fill='both',expand='yes')
    tk.Label(frm2,text = "验证码").pack(side='left')
    tk.Entry(frm2,width=50).pack(side='left')
    tk.Button(frm2, text = "发送验证码", command = sendacccode).pack(side='top',fill='both',expand='yes')

    tk.Button(logindlg, text = "登录", command = lambda:login(main_box,logindlg)).pack(side='top',fill='both',expand='yes')
    logindlg.grab_set()
    logindlg.mainloop()

def login(main_box,logindlg):
    url = "http://124.133.27.90:6082/rp/addressPriv"
    params = {"mobile":mobile.get()}
    res = requests.get(url=url,params=params)
    if res.status_code == 200:
        resjson = res.json()
        if 'error' in resjson:
            tkMessageBox.showinfo("错误","验证未通过")
        else:
            tkMessageBox.showinfo("信息","验证通过，许可区域为"+resjson['areaname'])
            logindlg.destroy()
            main_box.update()
            main_box.deiconify()
    else:
        tk.Message("服务器通信异常")

def sendacccode():
    pass
# loginform()
createMainForm()

